﻿using LiveCharts;
using LiveCharts.Defaults;
using LiveCharts.Wpf;

using PLCS.App.Shared.Extensions;
using PLCS.App.Shared.ViewModels;
using PLCS.Application.Contracts.ErrorLogApp.Dtos;
using PLCS.Client.IService.LogManager;

using Prism.Commands;

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

namespace PLCS.App.LogManager.ViewModels;

public class ErrorLogViewModel : NavigationPagedCurdViewModel<ErrorLogDto, ErrorLogEditDto, IErrorLogService>
{
    private string _startTime = string.Empty, _endTime = string.Empty;

    public string StartTime
    {
        get { return _startTime; }
        set { _startTime = value; RaisePropertyChanged(); }
    }

    public string EndTime
    {
        get { return _endTime; }
        set { _endTime = value; RaisePropertyChanged(); }
    }

    private string _kind;

    public string Kind
    {
        get { return _kind; }
        set { SetProperty(ref _kind, value); }
    }

    private string _code;

    public string Code
    {
        get { return _code; }
        set { SetProperty(ref _code, value); }
    }

    private string _source;

    public string Source
    {
        get { return _source; }
        set { SetProperty(ref _source, value); }
    }

    private bool _isBottomDrawerOpen;

    public bool IsBottomDrawerOpen
    {
        get { return _isBottomDrawerOpen; }
        set { SetProperty(ref _isBottomDrawerOpen, value); }
    }

    public DelegateCommand GenerateReportCommand { get; set; }

    private SeriesCollection _seriesCollection;

    public SeriesCollection SeriesCollection
    {
        get { return _seriesCollection; }
        set { SetProperty(ref _seriesCollection, value); }
    }

    private ObservableCollection<ErrorLogRankingViewModel> _errorRankingList;

    public ObservableCollection<ErrorLogRankingViewModel> ErrorRankingList
    {
        get { return _errorRankingList; }
        set { SetProperty(ref _errorRankingList, value); }
    }

    public ErrorLogViewModel(IErrorLogService service) : base(service)
    {
        GenerateReportCommand = new DelegateCommand(GenerateReport);
        SeriesCollection = new SeriesCollection();
    }

    private void GenerateReport()
    {
        IsBottomDrawerOpen = true;
        if (!DataGridList.Any())
            return;
        var group = DataGridList.GroupBy(x => x.Source);
        var res = group.Select(x => new { Title = x.Key, Values = x.Count() });
        SeriesCollection.Clear();
        foreach (var item in res)
        {
            SeriesCollection.Add(new PieSeries
            {
                Title = item.Title,
                Values = new ChartValues<ObservableValue> { new(item.Values) },
                DataLabels = true
            });
        }
        ErrorRankingList = DataGridList.GroupBy(x => x.Message)
            .Select(x => new ErrorLogRankingViewModel() { Message = x.Key, Source = x.ElementAt(0).Source, Count = x.Count() })
            .OrderByDescending(x => x.Count)
            .ToObservable();
    }

    public override async Task GetPageData(int pageIndex)
    {
        try
        {
            UpdateLoading(true);
            var res = await _service.GetListBySearchAsync((pageIndex - 1) * PageSize, PageSize, Code, Kind, Source, StartTime, EndTime);
            TotalCount = (int)res.TotalCount;
            SetPageCount();
            DataGridList = res.Items.ToObservable();
        }
        finally
        {
            UpdateLoading(false);
        }
    }

    public class ErrorLogRankingViewModel
    {
        public string Source { get; set; }
        public string Message { get; set; }
        public int Count { get; set; }
    }
}